<?php
/**
 * @package qBase
 * @subpackage sql
 *
 */

/**
 * QSqlDatabase represents an abstract SQL database
 *
 * @package qBase
 * @subpackage sql
 */
class QSqlDatabase extends QObject implements QIAllowSerialize 
{
	/**
	 * The name of the database
	 *
	 * @var string
	 */
	public $name;
	/**
	 * The collation of the database
	 *
	 * @var string
	 */
	public $collation;
	/**
	 * The charset of the database
	 *
	 * @var string
	 */
	public $charset;
	/**
	 * The tables of the database
	 *
	 * @var array Array of QSqlTable
	 */
	public $tables;
	/**
	 * The QSqlConnection where this database exists
	 *
	 * @var QSqlConnection
	 */
	public $connection;

	/**
	 * The constructor of QSqlDatabase
	 *
	 * @param QSqlConnection $connection
	 * @param string $name
	 * @param string $charset
	 * @param string $collation
	 */
	public function __construct(QSqlConnection $connection = null, $name = null, $charset = null, $collation = null)
	{
		$this->connection = $connection;
		$this->name = $name;
		$this->collation = $collation;
		$this->charset = $charset;
	}
	
	/**
	 * Gets the name of the database
	 *
	 * @return string
	 */
	public function getName()
	{
		return $this->name;
	}
	
	/**
	 * Sets a new name for the database, if it's linked to a connection then the action will be performed on the database
	 *
	 * @param string $new_name
	 */
	public function rename($new_name)
	{
		if ($new_name != $this->name)
		{
			if ($this->connection)
				$this->connection->renameDatabase($this->name, $new_name);
			$this->name = $new_name;
		}
	}
	
	/**
	 * Gets the collation of the database
	 *
	 * @return string
	 */
	public function getCollation()
	{
		return $this->collation;
	}
	
	/**
	 * Gets the charset of the database
	 *
	 * @return string
	 */
	public function getCharset()
	{
		return $this->charset;
	}
	
	/**
	 * Gets the connection of the database
	 *
	 * @return QSqlConnection
	 */
	public function getConnection()
	{
		return $this->connection;
	}

	/**
	 * Sets the collation of the database, if it's linked to a connection then the action will be performed on the database
	 *
	 * @param string $collation
	 */
	public function setCollation($collation)
	{
		if ($collation != $this->collation)
		{
			if ($this->connection)
				$this->connection->setDatabaseCollation($this->getName(), $collation);
			$this->collation = $collation;
		}
	}
	
	/**
	 * Sets the charset of the database, if it's linked to a connection then the action will be performed on the database
	 *
	 * @param string $charset
	 */
	public function setCharset($charset)
	{
		if ($charset != $this->charset)
		{
			if ($this->connection)
				$this->connection->setDatabaseCharset($this->getName(), $charset);
			$this->charset = $charset;
		}
	}
	
	/**
	 * Sets the connection of this database
	 *
	 * @param QSqlConnection $connection
	 */
	public function setConnection(QSqlConnection $connection)
	{
		$this->connection = $connection;
	}

	/**
	 * Gets the tables in the database
	 *
	 * @return array Array of QSqlTable
	 */
	public function getTables()
	{
		if ($this->tables)
			return $this->tables;
	}
	
	/**
	 * Gets the number of tables in the database
	 *
	 * @return integer
	 */
	public function countTables()
	{
		if ($this->tables)
			return count($this->tables);
	}
	
	/**
	 * Creates a table and adds it to the database if a connection is linked to this object
	 *
	 * @param QSqlTable $table
	 * @param boolean $drop_if_exists
	 */
	public function createTable(QSqlTable $table, $drop_if_exists = false)
	{
		if ($this->connection)
			$this->connection->createTable($this->getName(), $table, $drop_if_exists);
		$this->addTable($table);
	}
	
	/**
	 * Gets a table in tha database by name
	 * 
	 * @param string name
	 *
	 * @return QSqlTable $name
	 */
	public function getTable($name)
	{
		if ($this->tables)
			foreach ($this->tables as $table)
				if ($table->getName() == $name)
					return $table;
		return null;
	}
	
	/**
	 * Gets the table at the specified position
	 *
	 * @param integer $position
	 * @return QSqlTable
	 */
	public function getTableAt($position)
	{
		if ($this->tables)
		{
			if ($position < count($this->tables))
				return $this->tables[$position];
		}
		return null;
	}
	
	/**
	 * Loads table information from the linked connection. If the table already exists in this QSqlDatabase 
	 * it will be replaced
	 *
	 * @param QSqlTable $table_name
	 */
	public function loadTableInfo($table_name)
	{
		$this->loadTablesInfo(array($table_name));
		return $this->getTable($table_name);
	}
	
	/**
	 * Loads the tables information from the linked connection. If any table already exists in this QSqlDatabase 
	 * it will be replaced
	 * If $tables_names id null then we will get info about all the tables in the database
	 *
	 * @param array $tables_names Array of string
	 */
	public function loadTablesInfo($tables_names = null)
	{
		if (!$tables_names)
			$tables_names = $this->connection->getTablesInDatabase($this->getName());
		
		foreach ($tables_names as $tn)
		{
			$new_table = $this->connection->getTableInfo($this->getName(), $tn);
			if ($new_table)
				$this->addTable($new_table);
		}
	}
	
	/**
	 * This function only adds the table to this object's table list. If a table with the same name exists 
	 * it will be replaced
	 *
	 * @param QSqlTable $table
	 */
	private function addTable(QSqlTable $table)
	{
		$count = $this->countTables();
		
		if ($count > 0)
		{
			$found = false;
			for ($i = 0; $i < $count; $i++)
			{
				if ($this->tables[$i]->getName() == $table->getName())
				{
					$table->setDatabase($this);
					$this->tables[$i] = $table;
					$found = true;
					break;
				}
			}
			if (!$found)
			{
				$table->setDatabase($this);
				$this->tables[] = $table;
			}
		}
		else 
		{
			$table->setDatabase($this);
			$this->tables[] = $table;
		}
	}
	
	/**
	 * Drops the table from the database and removes it from this list.
	 *
	 * @param string $name
	 */
	public function dropTable($name)
	{
		$this->connection->dropTable($this->getName(), $name);
		
		// remove it form the list also
		$count = count($this->tables);
		
		for ($i = 0; $i < $count; $i++)
			if ($this->tables[$i]->getName() == $name)
			{
				$this->tables[$i]->unsetDatabase();
				array_splice($this->tables, $i, 1);
				break;
			}
	}
}

?>